package com.totobox.apps.activity;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.totobox.apps.Const;
import com.totobox.apps.R;
import com.totobox.apps.common.FileUtils;

public class FileDownExceuteActivity extends BasicActivity {

	private ImageButton btn_wait;
	private ImageButton btn_cancel;
	
	public LinearLayout down_list;
	
	private ProgressDialog progressDialog;
	final private int PROGRESS_DIALOG = 0;
	final private int ALERT_DIALOG= 1;
	
	public Thread dataThread = null;
	public Handler handler = new Handler();
	
	public List<ProgressBar> pbList = new ArrayList<ProgressBar>();
	public List<TextView> txtList = new ArrayList<TextView>();
	
	public int totalCnt = 0;
	private TextView progressTxt;
	public FileDownloadTask downTask;
	
	public int curPos = 0;
	public boolean isStop = false;
	public boolean isCanceled = false;
	public String dn_filename = "";
	
	//다운 경로 세팅
	public String downDir = "";
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);

		setContentView(R.layout.multi_file_download);
		
		progressTxt = (TextView) findViewById(R.id.total_file);
		
		btn_wait = (ImageButton) findViewById(R.id.btn_wait);
		btn_cancel = (ImageButton) findViewById(R.id.btn_cancel);
		
		btn_wait.setOnClickListener(this);
		btn_cancel.setOnClickListener(this);
		
		down_list = (LinearLayout) findViewById(R.id.down_list);
		
		//상단 타이틀 초기화
        super.initTitle();

        if("VOD".equals(Const.MENU)) downDir = Const.homeDir + Const.movieDir;
        else if("IMG".equals(Const.MENU)) downDir = Const.homeDir + Const.picDir;
        else if("AUD".equals(Const.MENU)) downDir = Const.homeDir + Const.musicDir;
        else if("ETC".equals(Const.MENU)) downDir = Const.homeDir + Const.etcDir;
        
        //진행 프로세스
		showDialog(PROGRESS_DIALOG);
		
		dataThread = new Thread(null, downData);
    	dataThread.start();
    	
	}

	@Override
	public void onClick(View v) {
		
		if(v == btn_wait){
			if(!isStop){
				isStop = true;
				//btn_wait.setText("이어받기");
				btn_wait.setImageDrawable(getResources().getDrawable(R.drawable.btn_down));
				try{ downTask.onCancelled(); }catch(Exception e){}
			}
			else{
				isStop = false;
				btn_wait.setImageDrawable(getResources().getDrawable(R.drawable.btn_stop));
				try{
					downTask = new FileDownloadTask();
					downTask.execute();
				}catch(Exception e){}
			}
		}
		
		if(v == btn_cancel){
			isStop = true;
			try{ downTask.onCancelled(); }catch(Exception e){}
			finish();
		}
		
		//이전 액티비티 이동
		if(v == btn_title_left){
			finish();
		}
			
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		return false;
	}

	/**
	 * 다운로드 파일 리스트
	 */
	private Runnable downData = new Runnable() {
    	public void run() {
    		try {
    			
		    	handler.post(dataResults);
		    	
    		} catch (Exception e) {
    			Log.d("partData : ", e.toString());
    		}
    	}
    };
    
    /**
     * 
     */
	private Runnable dataResults = new Runnable() {
    	public void run() {
    		try {
    			if (Const.dnQueue != null && !Const.dnQueue.isEmpty()) {
    				
    				totalCnt = Const.dnQueue.size();
    				
    				for(int i = 0 ; i < totalCnt ; i++){
    					down_list.addView(addDownList(i));
    				}
    			}
    			else{
    				showNotFoundData();
    			}
    			
    	    	progressDialog.dismiss();
    	    	FileDownExceuteActivity.this.removeDialog(PROGRESS_DIALOG);
    	    	
    	    	downTask = new FileDownloadTask();
				downTask.execute();
				
    		} catch (Exception e) {
    			Log.e("xml-data", e.toString());
    		}

    	}
    };
    
    private void showNotFoundData() {
    	Toast toast = Toast.makeText(this, "다운로드 파일이 없습니다.", Toast.LENGTH_SHORT);
    	toast.show();
    }
    
	@Override
	protected Dialog onCreateDialog (int id) {
		switch (id) {
		case PROGRESS_DIALOG:
			
			progressDialog = new ProgressDialog(this);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			progressDialog.setMessage("다운 목록 로딩중 입니다.");
			return progressDialog;
		case ALERT_DIALOG:
			return null;
		default:
			
			return null;
		}
	}
	
	
	public View addDownList(int position){
		
		LayoutInflater inflater = this.getLayoutInflater();
		View vw = inflater.inflate(R.layout.down_progress, null);
		
		ProgressBar progressBar = (ProgressBar)vw.findViewById(R.id.dn_progress_bar);
		progressBar.setId(position);
		
		TextView file_name = (TextView)vw.findViewById(R.id.file_name);
		file_name.setText(Const.dnQueue.get(position).get("vcName"));
		
		TextView txtView = (TextView)vw.findViewById(R.id.down_per);
		txtView.setText("0 %");
		
		pbList.add(progressBar);
		txtList.add(txtView);
		
		return  vw;
	}
	
	/**
     * 
     * @param i
     */
	public void checkFinishDown(int pos) {
		//현재 포지션
		curPos = pos;
		progressTxt.setText("다운로드 진행률 "+pos+" / " +totalCnt);
	}
	
	/**
	 * 파일을 다운 받으면 한번 호출 한다.
	 * @param jsonData
	 */
	public void finishFileDown(Map<String,String> jsonData){
		
	}
	
	/**
	 * 파일 다운로드
	 * @author taesu.yoo
	 *
	 */
	class FileDownloadTask extends AsyncTask<String, Integer, String> {

		boolean isCanceled = false;
		
		private int DOWNLOAD_DONE = 0;
		private int DEFAULT_TIMEOUT = 5000;
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			FileUtils.setMakeDir(downDir);
		}
		
		@Override
		protected String doInBackground(String... strData) {
			
			int count;
			
			URL url = null;
			BufferedInputStream bis = null;
			BufferedOutputStream bos = null;
			
			//현재 다운 받는 파일을 중지 한거니 다시 다운 시도
			if(curPos > 0 ) curPos--;
			long remains = 0;
			
			long biFileSize = 0l;
			String http_url = "";
			
			Map<String,String> jsonData = null;
			byte data[] = new byte[1024];
			for(int i = curPos ; i < totalCnt ; i++){
				
				try {
					
					jsonData = Const.dnQueue.get(i);
					
					//파일 명
					dn_filename = downDir + jsonData.get("vcName") + "." + jsonData.get("vcFileExtend");
					
					//인터페이스에서 데이터 가져와 고화질 아닌것은 무조건 일반질
					if("H".equals(Const.MODE)){
						biFileSize = Long.parseLong(jsonData.get("biHighFileSize"));
						http_url = jsonData.get("vcHighDown");
					}
					else{
						biFileSize = Long.parseLong(jsonData.get("biFileSize"));
						http_url = jsonData.get("vcOriginDown");
					}
					
					File file = new File(dn_filename);
					if (file.exists() == false) {
						file.createNewFile();
					}

					RandomAccessFile raf = new RandomAccessFile(file.getAbsolutePath(), "rw");
				    long fileSize = raf.length(); 
				    raf.seek(fileSize); 
				        
					//publishProgress(i , 0);
					
					//파일 다운 준비
					url = new URL(http_url);
					URLConnection conn = url.openConnection(); 
			        conn.setRequestProperty("Range", "bytes=" + String.valueOf(fileSize) + '-'); //이어받기부분
			        conn.connect();
			        
			        conn.setConnectTimeout(DEFAULT_TIMEOUT); 
			        conn.setReadTimeout(DEFAULT_TIMEOUT); 
			        remains = conn.getContentLength(); 
			        long lenghtOfFile = remains + fileSize; 
			         
			        if (!(remains <= DOWNLOAD_DONE) || (remains == fileSize)) { 
						
						bis = new BufferedInputStream(url.openStream());
	
						long total = fileSize;
						while ((count = bis.read(data)) != -1 ) {
							
							total += count;
							publishProgress(i , (int) (total * 100 / lenghtOfFile));
							raf.write(data, 0, count); 
							
							if(isStop) synchronized (this) {wait();}
							
							if(isCancelled()) break;
						}
						
						raf.close();
			        }
						
				} catch (Exception e) {
	                e.printStackTrace();
	            } finally {
	            	if(!isStop || !isCancelled()) dn_filename = null;
	            	finishFileDown(jsonData);
	                try{ if( bos != null ) bos.close(); }catch(Exception ex){}
	                try{ if( bis != null ) bis.close(); }catch(Exception ex){}
	            }
			}
			return null;
		}
		
		@Override
		protected void onCancelled() {
			
			isCanceled = true;
			new File(downDir + dn_filename).delete();
			super.onCancelled();
		}

		// publishProgress(…) 메소드 호출의 callback
		@Override
		protected void onProgressUpdate(Integer... args) {
			 
			pbList.get(args[0]).setProgress(args[1]);
			txtList.get(args[0]).setText(args[1] + " %");
			
			//진행율 업데이트
			if(curPos < (args[0]+1)){
				curPos = args[0]+1;
				checkFinishDown(curPos);
			}
		}

		@Override
		protected void onPostExecute(String unused) {
			if(isCanceled)
				new File(downDir + dn_filename).delete();
		}

	}
	
	/**
	 * 파일명 생성
	 * @param wholePath
	 * @return
	 */
	public String getFileName(String wholePath)
    {
        String name=null;
        int start,end;
        start=wholePath.lastIndexOf('/');
        end=wholePath.length();
        name=wholePath.substring((start+1),end);
        return name;
    }

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		
		if(dn_filename != null && dn_filename.length()>0)
			new File(downDir + dn_filename).delete();
	}

	
}